﻿import D3D.Vertex;
import D3D.Matrix;
import D3D.Style;
class D3D.Polygon
{
	//属性
	private var center : Vertex;
	public var screen : Object;
	public var style : Style;
	private var vertexs : Array;
	private var fixVertexC : Vertex;
	private var m : Matrix;
	public var pname : String;
	private var preShowTag : MovieClip;
	public var z : Number;
	/*
	line1 : 1,所有点连成一条线
	line2 : 2, 每两点连成一条线
	face1 : 3, 所有点连成一面
	face2 : 4, 每三个不重用的点连成一个面
	face3 : 5,每三个点连成一个面重用1个点
	face4 : 6,每三个点连成一个面重用2个点
	face5 : 7,每四个不重用的点连成一个面
	face6 : 8,每四个点连成一个面重用1个点
	face7 : 9,每四个点连成一个面重用2个点
	
	*/
	public var defaultDrawType : Number;
	public static var drawType : Object = {
		line : 1, face : 2
	}
	private var father : Object;
	private var child : Array;
	private var me : Object;
	//构造函数
	public function Polygon (__name : String, _drawType : Number)
	{
		if (__name == undefined)
		{
			say ("未定义Polygon名子");
			return;
		} else
		{
			if (_drawType != undefined)
			{
				defaultDrawType = _drawType;
			}
			if (defaultDrawType > 2 || defaultDrawType == undefined)
			{
				defaultDrawType = 2;
			}
			screen = undefined;
			vertexs = new Array ();
			pname = __name;
			center = new Vertex ();
			father = new Object ();
			child = new Array ();
			z = 0;
			fixVertexC = new Vertex ();
			m = new Matrix ();
			me = this;
		}
	}
	//------------------------------  功能区  --------------------------------
	//////////////////////////////////////////////////////////////////////
	//
	//旋转polygon中心点
	//
	public function RotationCenter (x, y, z)
	{
		fixVertexC = fixVertexC.plus (new Vertex (x, y, z));
		var matrix : Matrix;
		if (me.screen.matrix != undefined)
		{
			matrix = me.screen.matrix;
		}else
		{
			matrix = me.m;
		}
		me.center = matrix.zRotation (me.center, x, y, z);
		
		//-------child
		me.RotationChild(x,y,z);
		
		//	me.Draw(preShowTag);
		
	}
	//
	//旋转polygon内点
	//
	public function Rotation (x, y, z)
	{
		var matrix : Matrix;
		if (me.screen.matrix != undefined)
		{
			matrix = me.screen.matrix;
		}else
		{
			matrix = me.m;
		}
		vertexs = matrix.zRotation (vertexs, x, y, z);
		//	me.Draw(preShowTag);
		
	}
	///
	//移动整个polygon 到 x,y,z位置
	///
	public function MoveCenterTo(x:Number,y:Number,z:Number){
		if(x!=undefined&& y!=undefined && z!=undefined)
		{
			var vl:Vertex=(new Vertex(x,y,z)).deduct(me.center);
			me.center=(new Vertex(x,y,z));
			
			me.MoveChild(vl);
		}
	}
	//
	//相对移动整个polygon x,y,z位移
	//
	public function MoveCenter(x:Number,y:Number,z:Number){
		if(x!=undefined&& y!=undefined && z!=undefined)
		{
			me.center=me.center.plus(new Vertex(x,y,z));
			me.MoveChild(x,y,z);
		}
		
	}
	//
	//相对移动polygon中所有点 x,y,z位移
	//
	public function Move(x:Number,y:Number,z:Number){
		for(var i in vertexs)
		{
			vertexs[i]=vertexs[i].plus(new Vertex(x,y,z))
		}
	}
	public function addChild (p : Polygon, v : Number) : Boolean
	{
		if (p != undefined)
		{
			for (var i in child)
			{
				if (child [i] == p)
				{
					say ("已经加入了这个子骨关节");
					return true;
				}
			}
			//---------- 加入字关节部分动作
			child.push (p);
			//var vv:Vertex=me.vertexs[v].deduct(p.center);
			p.center=me.vertexs[v].plus(me.center);
			p.addFather (this,v);
			//------------------------------
			return true;
		} else
		{
			say ("子骨关节不正确!");
			return false;
		}
	}
	public function delChild (p : Polygon) : Boolean
	{
		if (p != undefined)
		{
			var childs : Array = new Array ();
			for (var i in child)
			{
				if (child [i] != p)
				{
					childs.push (child [i]);
				} else
				{
					p.delFather ();
				}
			}
			child = childs;
			return true;
		} else
		{
			return false;
		}
	}
	public function addFather (p : Polygon, v : Number) : Boolean
	{
		if (p != undefined)
		{
			father.polygon = p;
			father.vertex = v;
			return true;
		} else
		{
			say ("加入父关节不正确!")
			return false;
		}
	}
	public function delFather ()
	{
		father = new Object ();
	}
	private function getVertexByIndex (indexs : Number) : Vertex
	{
		var rv = me.vertexs [indexs];
		if (indexs != undefined && rv != undefined)
		{
			return rv;
		} else
		{
			trace ("没有找到点");
			return undefined;
		}
	}
	private function RotationChild (x:Number, y:Number, z:Number)
	{
		for (var i in child)
		{
			child [i].RotationCenter (x, y, z);
		}
	}
	private function MoveChild (x, y, z)
	{
		for (var i in child)
		{
			child [i].MoveCenter (x, y, z);
		}
	}
	private function DrawChild(tag:MovieClip){
		for (var i in child)
		{
			child [i].DrawPolygon(tag);
		}
	}
	public function addVertex (vertex) : Number
	{
		if (vertex == undefined)
		{
			say ("加入VERTEX类型点出错,数据不能为空.");
			return -1;
		} else if (vertex.length > 1)
		{
			var i : Number = 0;
			var b : Boolean;
			while (i < vertex.length)
			{
				b = me.addVertex (vertex [i]);
				i ++;
			}
			return 0;
		} else if (vertex.x != undefined)
		{
			var index:Number=vertexs.push (vertex);
			setDepth ();
			return index-1;
		} else
		{
			say ("加入的VERTEX类型不正确");
			return -1;
		}
	}
	/**  绘制图形
	*
	* @usage
	* @param   tag  如果没有定义screen 则输入绘制的目标movieClip
	* @param   type 绘制方式 Polygon.drawType类型
	* @return
	*/
	public function Draw (tag : MovieClip , vertex : Array , type : Number) : Boolean
	{
		var vertexa = new Array ();
		vertexa = vertex;
		if (tag != undefined)
		{
			preShowTag = tag;
		} else
		{
			say ("绘制目标错误");
		}
		if (type != undefined && type <= 2)
		{
			defaultDrawType = type;
		}
		switch (defaultDrawType)
		{
			//draw line
			case 1 :
			var depthd : Number = preShowTag.getNextHighestDepth ();
			if (depthd > 1040000)
			{
				depthd = 1;
			}
			var pln : String = me.pname + "_p";
			var mt:MovieClip=eval(eval(preShowTag)+"."+pln);
			if (mt!= undefined)
			{
				clears (mt);
			}else
			{
				
				preShowTag.createEmptyMovieClip (pln, depthd);
				//trace(pln=" d="+depthd);
				
			}
			drawLine (preShowTag [pln] , vertexa, me.style);
			break;
			//draw face
			case 2 :
			var depthd : Number = preShowTag.getNextHighestDepth ();
			if (depthd > 1040000)
			{
				depthd = 1;
			}
			var pln : String = me.pname + "_p";
			
			var mt:MovieClip=eval(eval(preShowTag)+"."+pln);
			if (mt!= undefined)
			{
				clears (mt);
			}else
			{
				
				preShowTag.createEmptyMovieClip (pln, depthd);
				trace(pln=" d="+depthd);
				
			}
			drawFace (preShowTag [pln] , vertexa, me.style);
			break;
		}
		//DrawChild(tag);
		return true;
	}
	public function DrawPolygon (tag : MovieClip, type : Number) : Boolean
	{
		var vertexa = new Array ();
		vertexa = localToScreen (vertexs);
		//vertexa=vertexs;
		if (tag != undefined)
		{
			preShowTag = tag;
		} else
		{
			say ("绘制目标错误");
		}
		if (type != undefined && type <= 2)
		{
			defaultDrawType = type;
		}
		Draw (tag, vertexa, type);
		return true;
	}
	private function setDepth ()
	{
		
		var n : Number = 0;
		var tt : Number = 0;
		for (var i in vertexs)
		{
			tt += vertexs [i].z;
		}
		me.z = Math.floor (tt / n);
		
	}
	private function clears (tag, lists)
	{
		tag.clear ();
		
		//trace (tag);
		if (lists == undefined)
		{
			lists = new Array ();
		}
		lists.push (tag);
		for (var i in tag)
		{
			if (typeof (tag [i]) == "movieclip" )
			{
				var b = true;
				for (var l in lists)
				{
					if (tag [i] == lists [l])
					{
						b = false;
						break;
					}
				}
				if (b)
				{
					me.clears (tag [i] , lists);
				}
			}
		}
	}
	private function drawFace (tag : MovieClip, vertex : Array, style : Style) : Boolean
	{
		if (vertexs.length < 3)
		{
			say ("数据不正确");
			return false;
		}
		if (style == undefined)
		{
			//trace("un1");
			style = screen.style;
			if (style == undefined)
			{
				//trace("un2");
				style == new Style ();
			}
		}
		//style.toString();
		if (style.lco != undefined)
		{
			tag.lineStyle (style.lth, style.lco , style.lal);
		}
		if (style.fco != undefined)
		{
			tag.beginFill (style.fco , style.fal);
		}
		/////////--
		tag.moveTo (vertex [0].x, vertex [0].y);
		var i : Number = 1;
		while (i < vertex.length)
		{
			tag.lineTo (vertex [i].x, vertex [i].y);
			i ++;
		}
		////////////////////////////////////
		if (style.fco != undefined)
		{
			tag.endFill ();
		}
		return true;
	}
	private function drawLine (tag : MovieClip, vertex : Array, style : Style) : Boolean
	{
		if (vertexs.length < 2)
		{
			say ("数据不正确");
			return false;
		}
		if (style == undefined)
		{
			style = screen.style;
			if (style == undefined)
			{
				style == new Style ();
			}
		}
		if (style.lco != undefined)
		{
			tag.lineStyle (style.lth, style.lco , style.lal);
		}
		/////////--
		tag.moveTo (vertex [0].x, vertex [0].y);
		var i : Number = 1;
		while (i < vertex.length)
		{
			tag.lineTo (vertex [i].x, vertex [i].y);
			i ++;
		}
		////////////////////////////////////
		return true;
	}
	//功能函数
	public function localToScreen (v)
	{
		if (v != undefined)
		{
			if (v [0].x != undefined)
			{
				var rv : Array = new Array ();
				var i = 0;
				while (i < v.length)
				{
					rv.push (me.localToScreen (v [i]));
					i ++;
				}
				return rv;
			} else if (v.x != undefined)
			{
				var rvs : Vertex = new Vertex ();
				rvs = me.m.zRotation (v, fixVertexC.x, fixVertexC.y, fixVertexC.z);
				rvs = rvs.plus (me.center);
				/*
				if(me.screen==undefined){
				rvs=rvs.plus(me.screen.center);
				}
				*/
				return (rvs);
			}
		}else{
			var rv:Array=new Array();
			rv=localToScreen(me.vertexs);
			return rv;
		}
	}
	
	public function toString ()
	{
		trace ("----- " + me.pname + " -----");
		trace ("screen:" + ((screen != undefined) ? "有" : "无"));
		me.style.toString ();
		trace ("以下Vertex:");
		for (var i = 0; i < vertexs.length; i ++)
		{
			vertexs [i].toString ();
		}
		trace ("---------------------------");
	}
	private function say (obj : Object)
	{
		trace ("Polygon["+me.pname+"]:" + obj);
	}
	//get set
	public function get x () : Number
	{
		return center.x;
	}
	public function get y () : Number
	{
		return center.y;
	}
	
	public function set x (v : Number)
	{
		//me.Move (v, 0, 0);
		me.center.x += v;
		//me.Draw (preShowTag);
	}
	public function set y (v : Number)
	{
		//me.Move (0, v, 0);
		me.center.y += v;
		//me.Draw (preShowTag);
	}
	
}
